#include "StdAfx.h"
#include "NormalizedManImage.h"
#include "structs.h"
#include "Panel.h"

NormalizedManImage::NormalizedManImage(DICOMStruct * dicomStruct):
	dicomStruct(dicomStruct),
	_normalizedData(NULL),
	_DIBData(NULL){
	doNormalization();
}

NormalizedManImage::~NormalizedManImage(void)
{
}

void NormalizedManImage::doNormalization(){
	if(dicomStruct != NULL && !*dicomStruct->isNormalized && Panel::mEMManager->getImageBuffer(dicomStruct) != NULL){
		*dicomStruct->isNormalized = true;		
		int width = dicomStruct->imageParameters.width * dicomStruct->imageParameters.samplesPerPixel;
		int height = dicomStruct->imageParameters.height;		
		int bitsAllocated = 32;
		int bitsStored = dicomStruct->imageParameters.bitsStored;
		int highBit = dicomStruct->imageParameters.highBit;
		int numberOfPixel;
		BOOLEAN pixelRepresentation;
		pixelRepresentation = false;
		if(dicomStruct->imageParameters.pixelRepresentation == 1){
			pixelRepresentation = true;
		}else{
			if(dicomStruct->imageParameters.pixelRepresentation == 0)
				pixelRepresentation = false;
			else
				int g = 5;
		}		
		unsigned int complement;
		unsigned int valueOfHighBit;				
		unsigned char * pImageNew = new unsigned char[width * height * getSizePixel(dicomStruct)];		
		void * pixel;
		unsigned int value;
		int minValue = 99999;
		int maxValue = -99999;	
		void * destPointer = NULL;
		//pixelRepresentation = 0;
		for(int i = 0; i < height ; i++){
			for(int j = 0; j < width; j++){
				numberOfPixel = width * i + j;				
				if(dicomStruct->imageParameters.samplesPerPixel == 1){
					int numberOfByte = numberOfPixel * dicomStruct->imageParameters.bitsAllocated / 8;				
					pixel = (unsigned char *) Panel::mEMManager->getImageBuffer(dicomStruct) + numberOfByte;
					value = *(unsigned int *)pixel;							
					value = value >> (numberOfPixel * dicomStruct->imageParameters.bitsAllocated) % 8;
					int difference = bitsAllocated - bitsStored;	
					if(pixelRepresentation){		
						complement = 0xFFFFFFFF;							
						valueOfHighBit = value;	
						valueOfHighBit = valueOfHighBit << difference;
						complement = complement >> difference;
						value = value & complement;
						valueOfHighBit = valueOfHighBit & 0x80000000;						
						complement = 0;
						//valueOfHighBit = valueOfHighBit >> 1;
						if(valueOfHighBit != 0){
							for(int i = 0; i < difference; i++){
								complement += valueOfHighBit;
								valueOfHighBit = valueOfHighBit >> 1;
							}
							value = value | complement;	
						}else{
							//value = value;
						}						
					}else{								
						unsigned int complement = 0xFFFFFFFF;						
						complement = complement >> difference;
						value = value & complement;	
					}						
					if(dicomStruct->maxValue < (int)value)
						dicomStruct->maxValue = (int)value;
					if((int)value < minValue )
						minValue = (int)value;
					if((int)value > maxValue )
						maxValue = (int)value;
					dicomStruct->minValue = (int)minValue;							
					destPointer = pImageNew + (numberOfPixel * getSizePixel(dicomStruct));
				}else{					
					if(dicomStruct->imageParameters.planarConfiguration == 0						
						){			
						value = *((unsigned char *)Panel::mEMManager->getImageBuffer(dicomStruct) + numberOfPixel);						
						destPointer = pImageNew + (numberOfPixel * getSizePixel(dicomStruct));
					}else{
						value = *((unsigned char *)Panel::mEMManager->getImageBuffer(dicomStruct) + numberOfPixel);				
						int aa = width * height / 3;						
						destPointer = pImageNew + ((numberOfPixel % aa * 3 + numberOfPixel / aa - 0) * getSizePixel(dicomStruct));
					}
					if(dicomStruct->maxValue < (int)value)
						dicomStruct->maxValue = (int)value;
					if((int)value < minValue )
						minValue = (int)value;
					if((int)value > maxValue )
						maxValue = (int)value;
					dicomStruct->minValue = (int)minValue;
				}
				if(getSizePixel(dicomStruct) == 1){
					*(unsigned char *)destPointer = (unsigned char)value;
					//memcpy(destPointer, &value, 1);
				}
				if(getSizePixel(dicomStruct) == 2){					
					*(unsigned short *)destPointer = (unsigned short)value;
				//	unsigned short p = *(unsigned short *)destPointer;
				//	int g = 1;
				}
				if(getSizePixel(dicomStruct) == 4)
					*(unsigned int *)destPointer = (unsigned int)value;
				//*(unsigned int *)destPointer = value;
			}
		}	
				
		Panel::mEMManager->setImageBuffer(dicomStruct, pImageNew,  width * height * getSizePixel(dicomStruct));		
		if(dicomStruct->imageParameters.PhotometricInterpretation == YBR_FULL
			//|| 	dicomStruct->imageParameters.PhotometricInterpretation == YBR_FULL_422)
			){
			convertYBRFULLtoRGB(Panel::mEMManager->getImageBuffer(dicomStruct), Panel::mEMManager->getImageBuffer(dicomStruct), dicomStruct->imageParameters.width, dicomStruct->imageParameters.height);				
		}	
		if(dicomStruct->orient == -1){			
			turnVertStruct(dicomStruct);	
			dicomStruct->numberOfVerTurns = 0;
		}		

		if(dicomStruct->representationParameters.windowValue == 0){
			dicomStruct->representationParameters.windowValue = maxValue - minValue;		
			dicomStruct->representationParameters.levelValue = (maxValue + minValue) / 2;
		}
		dicomStruct->representationParameters.LevelValueConst = dicomStruct->representationParameters.levelValue;
		dicomStruct->representationParameters.windowValueConst = dicomStruct->representationParameters.windowValue;
		pixel = NULL;
		destPointer = NULL;		
	}
}

void NormalizedManImage::convertYBRFULLtoRGB(void * destImg, void * sourseImg, int width, int height){
	unsigned int buffer1;
	unsigned int buffer2;
	unsigned int buffer3;
	for(int i = 0; i < width * height; i ++){
		int off = i * 3;
		buffer1 = (float)(*((unsigned char *)sourseImg + off + 0)) + 1.402 * ((float)(*((unsigned char *)sourseImg + off + 2)) - 128.0);		
		buffer2 = (float)(*((unsigned char *)sourseImg + off + 0)) - 0.344136 * ((float)(*((unsigned char *)sourseImg + off + 1)) - 128.0) - 0.714136 * ((float)(*((unsigned char *)sourseImg + off + 2)) - 128.0);				
		buffer3 = (float)(*((unsigned char *)sourseImg + off + 0)) + 1.772 * ((float)(*((unsigned char *)sourseImg + off + 1)) - 128.0);							
		*((unsigned char *)destImg + off + 0) = buffer1;
		*((unsigned char *)destImg + off + 1) = buffer2;
		*((unsigned char *)destImg + off + 2) = buffer3;		
	}	
	return;
}

void NormalizedManImage::turnVertStruct(DICOMStruct * dicomStruct){		
	int width = dicomStruct->imageParameters.width * dicomStruct->imageParameters.samplesPerPixel;
	int height = dicomStruct->imageParameters.height;
	char *  buffer;	
	buffer = new char [width * getSizePixel(dicomStruct)];	
	for(int i = 0; i < height / 2 ; i++){			
		memcpy(buffer,(((char *)Panel::mEMManager->getImageBuffer(dicomStruct) + i * width * getSizePixel(dicomStruct))), width * getSizePixel(dicomStruct));
		memcpy((((char *)Panel::mEMManager->getImageBuffer(dicomStruct) + i * width * getSizePixel(dicomStruct))), (((char *)Panel::mEMManager->getImageBuffer(dicomStruct) + (height - i - 1) * width * getSizePixel(dicomStruct))), width * getSizePixel(dicomStruct));
		memcpy((((char *)Panel::mEMManager->getImageBuffer(dicomStruct) + (height - i - 1) * width * getSizePixel(dicomStruct))), buffer, width * getSizePixel(dicomStruct));
	}			
	if(dicomStruct->numberOfRotations == 0 || dicomStruct->numberOfRotations == 2 
		|| dicomStruct->numberOfRotations == 4){
			if(dicomStruct->numberOfVerTurns == 0)
				dicomStruct->numberOfVerTurns = 1;
			else
				dicomStruct->numberOfVerTurns = 0;
	}else{
		if(dicomStruct->numberOfHorTurns == 0)
			dicomStruct->numberOfHorTurns = 1;
		else
			dicomStruct->numberOfHorTurns = 0;		
	}	
	delete buffer;
	return;	
}
/*
Graphics NormalizedManImage::getGDIPlusDIB(){
	
}*/